#import('dart:html');
#import('dart:json');

Element messageContent;
ButtonElement runButton;
DivElement statusText;
OutputArea output;
Element editor;
IFrameElement frameArea;

num startTime = 0;

void main() {
  setupUI();

  showMessage('Welcome to Dart!');
}

void showMessage(String message) {
  //var textElement = query('#pg_messages');

  //messageContent.text = message;
}

void setupUI() {
//  Element root = query("#playground");
//  window.on.resize.add((e) {
//    root.rect.then((r) => resize(r));
//  });

  runButton = query("#pg_run");
  runButton.on.click.add(run);

  statusText = query("#pg_status");


  // edit area
  editor = query("#pg_editor textarea");

  // iframe area
  frameArea = query("#pg_frame iframe");
  //Window frameWindow = frameArea.contentWindow;
  window.on.message.add(handleFrameMessage);

  // output area
  output = new OutputArea(query("#pg_output pre"));

  //root.rect.then((r) => resize(r));
}

void resize(ElementRect rect) {
  int width = rect.client.width;
  int height = rect.client.height;


}

/**
 * Display the given text in a status field.
 */
set status(String text) => statusText.text = text;

void run(Event event) {
  runButton.disabled = true;
  status = "compiling...";

  output.writeOk(" ");

  sendCompileRequest(editor.text);

  //window.setTimeout(finished, 1500);
}

void finished() {
  runButton.disabled = false;
}

void makeAbsolute(Element e) {
  e.style.position = 'absolute';
}

void sendCompileRequest(String text) {
  startTime = new Date.now().millisecondsSinceEpoch;

  HttpRequest req = new HttpRequest();

  Location l = window.location;

  req.open("POST", "${l.protocol}//${l.host}/compiler");

  req.on.readyStateChange.add((Event e) {
    if (req.readyState == HttpRequest.DONE) {
      handleCompileResponse(req);
    }
  });

  req.send(JSON.stringify({ "text" : text }));
}

void handleCompileResponse(HttpRequest req) {
  if (req.status == 200 || req.status == 0) {
    var result = JSON.parse(req.responseText);
    String jsOutput = result["result"];

    num millis = new Date.now().millisecondsSinceEpoch - startTime;

    status = "${(millis / 1000.0).toStringAsPrecision(2)}s";
    output.chModeStdout();

    finished();

    replaceIFrame(jsOutput);
  } else {
    // Show the error.
    output.writeError(req.toString());
    status = "";

    finished();
  }
}

void handleFrameMessage(var event) {
  String message = event.data;

  output.writeStdout(message);
}

void replaceIFrame(String source) {
  Location l = window.location;

  String host = "${l.protocol}//${l.host}";

  frameArea.srcdoc =
"""<!DOCTYPE html>

<html>
<head>
<style>
body {
  background-color: #FEFEFE;
  font-family: 'Open Sans', sans-serif;
  font-size: 14px;
  font-weight: normal;
  margin: 15px;
}

h1 {
  text-align: center;
}

p {
  color: #333;
}
</style>
</head>
<body>
<script>
${source}

// patch up the console.log function
var oldConsoleLog = console.log;

writeFn = function(arg) {
  //var domain = window.location.toString();
  window.parent.postMessage(
    arg.toString() + "\\n", "${host}/compiler");
};

//document.write = writeFn;
console.log = writeFn;
</script>
</body>
</html>""";
}

class OutputArea {
  PreElement out;

  bool stdout = false;
  bool ok = true;
  bool error = false;

  OutputArea(this.out) {

  }

  void writeOk(String str) {
    chModeOk();

    out.text = "${str}";
  }

  void writeError(String str) {
    chModeError();

    out.text = "${str}";
  }

  void writeStdout(String str) {
    chModeStdout();

    out.text = "${out.text}${str}";
    out.scrollByLines(100);
  }

  void clear() {
    out.text = "";
  }

  void chModeStdout() {
    if (!stdout) {
      _chMode("output");
      stdout = true;
    }
  }

  void chModeOk() {
    if (!ok) {
      _chMode("ok");
      ok = true;
    }
  }

  void chModeError() {
    if (!error) {
      _chMode("error");
      error = true;
    }
  }

  void _chMode(String mode) {
    out.parent.classes.clear();
    out.parent.classes.add(mode);

    out.text = "";

    stdout = false;
    ok = false;
    error = false;
  }

}
